Package com.mxgraph.canvas

Source Code of com.mxgraph.canvas.mxSvgCanvas

/**
* $Id: mxSvgCanvas.java,v 1.56 2010-08-02 13:14:43 david Exp $
* Copyright (c) 2007, Gaudenz Alder
*/
package com.mxgraph.canvas;

import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;

/**
* An implementation of a canvas that uses SVG for painting. This canvas
* ignores the STYLE_LABEL_BACKGROUNDCOLOR and
* STYLE_LABEL_BORDERCOLOR styles due to limitations of SVG.
*/
public class mxSvgCanvas extends mxBasicCanvas
{

  /**
   * Holds the HTML document that represents the canvas.
   */
  protected Document document;

  /**
   * Constructs a new SVG canvas for the specified dimension and scale.
   */
  public mxSvgCanvas()
  {
    this(null);
  }

  /**
   * Constructs a new SVG canvas for the specified bounds, scale and
   * background color.
   */
  public mxSvgCanvas(Document document)
  {
    setDocument(document);
  }

  /**
   *
   */
  public void appendSvgElement(Element node)
  {
    if (document != null)
    {
      document.getDocumentElement().appendChild(node);
    }
  }

  /**
   *
   */
  public void setDocument(Document document)
  {
    this.document = document;
  }

  /**
   * Returns a reference to the document that represents the canvas.
   *
   * @return Returns the document.
   */
  public Document getDocument()
  {
    return document;
  }

  /*
   * (non-Javadoc)
   * @see com.mxgraph.canvas.mxICanvas#drawCell()
   */
  public Object drawCell(mxCellState state)
  {
    Map<String, Object> style = state.getStyle();
    Element elem = null;

    if (state.getAbsolutePointCount() > 1)
    {
      List<mxPoint> pts = state.getAbsolutePoints();

      // Transpose all points by cloning into a new array
      pts = mxUtils.translatePoints(pts, translate.x, translate.y);

      // Draws the line
      elem = drawLine(pts, style);

      // Applies opacity
      float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY,
          100);

      if (opacity != 100)
      {
        String value = String.valueOf(opacity / 100);
        elem.setAttribute("fill-opacity", value);
        elem.setAttribute("stroke-opacity", value);
      }
    }
    else
    {
      int x = (int) state.getX() + translate.x;
      int y = (int) state.getY() + translate.y;
      int w = (int) state.getWidth();
      int h = (int) state.getHeight();

      if (!mxUtils.getString(style, mxConstants.STYLE_SHAPE, "").equals(
          mxConstants.SHAPE_SWIMLANE))
      {
        elem = drawShape(x, y, w, h, style);
      }
      else
      {
        int start = (int) Math.round(mxUtils.getInt(style,
            mxConstants.STYLE_STARTSIZE,
            mxConstants.DEFAULT_STARTSIZE)
            * scale);

        // Removes some styles to draw the content area
        Map<String, Object> cloned = new Hashtable<String, Object>(
            style);
        cloned.remove(mxConstants.STYLE_FILLCOLOR);
        cloned.remove(mxConstants.STYLE_ROUNDED);

        if (mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true))
        {
          elem = drawShape(x, y, w, start, style);
          drawShape(x, y + start, w, h - start, cloned);
        }
        else
        {
          elem = drawShape(x, y, start, h, style);
          drawShape(x + start, y, w - start, h, cloned);
        }
      }
    }

    return elem;
  }

  /*
   * (non-Javadoc)
   * @see com.mxgraph.canvas.mxICanvas#drawLabel()
   */
  public Object drawLabel(String label, mxCellState state, boolean html)
  {
    mxRectangle bounds = state.getLabelBounds();

    if (drawLabels)
    {
      int x = (int) bounds.getX() + translate.x;
      int y = (int) bounds.getY() + translate.y;
      int w = (int) bounds.getWidth();
      int h = (int) bounds.getHeight();
      Map<String, Object> style = state.getStyle();

      return drawText(label, x, y, w, h, style);
    }

    return null;
  }

  /**
   * Draws the shape specified with the STYLE_SHAPE key in the given style.
   *
   * @param x X-coordinate of the shape.
   * @param y Y-coordinate of the shape.
   * @param w Width of the shape.
   * @param h Height of the shape.
   * @param style Style of the the shape.
   */
  public Element drawShape(int x, int y, int w, int h,
      Map<String, Object> style)
  {
    String fillColor = mxUtils.getString(style,
        mxConstants.STYLE_FILLCOLOR, "none");
    String strokeColor = mxUtils.getString(style,
        mxConstants.STYLE_STROKECOLOR);
    float strokeWidth = (float) (mxUtils.getFloat(style,
        mxConstants.STYLE_STROKEWIDTH, 1) * scale);

    // Draws the shape
    String shape = mxUtils.getString(style, mxConstants.STYLE_SHAPE);
    Element elem = null;
    Element background = null;

    if (shape.equals(mxConstants.SHAPE_IMAGE))
    {
      String img = getImageForStyle(style);

      if (img != null)
      {
        elem = document.createElement("image");

        elem.setAttribute("x", String.valueOf(x));
        elem.setAttribute("y", String.valueOf(y));
        elem.setAttribute("width", String.valueOf(w));
        elem.setAttribute("height", String.valueOf(h));

        elem.setAttributeNS(mxConstants.NS_XLINK, "xlink:href", img);
      }
    }
    else if (shape.equals(mxConstants.SHAPE_LINE))
    {
      String direction = mxUtils.getString(style,
          mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
      String d = null;

      if (direction.equals(mxConstants.DIRECTION_EAST)
          || direction.equals(mxConstants.DIRECTION_WEST))
      {
        int mid = (y + h / 2);
        d = "M " + x + " " + mid + " L " + (x + w) + " " + mid;
      }
      else
      {
        int mid = (x + w / 2);
        d = "M " + mid + " " + y + " L " + mid + " " + (y + h);
      }

      elem = document.createElement("path");
      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_ELLIPSE))
    {
      elem = document.createElement("ellipse");

      elem.setAttribute("cx", String.valueOf(x + w / 2));
      elem.setAttribute("cy", String.valueOf(y + h / 2));
      elem.setAttribute("rx", String.valueOf(w / 2));
      elem.setAttribute("ry", String.valueOf(h / 2));
    }
    else if (shape.equals(mxConstants.SHAPE_DOUBLE_ELLIPSE))
    {
      elem = document.createElement("g");
      background = document.createElement("ellipse");
      background.setAttribute("cx", String.valueOf(x + w / 2));
      background.setAttribute("cy", String.valueOf(y + h / 2));
      background.setAttribute("rx", String.valueOf(w / 2));
      background.setAttribute("ry", String.valueOf(h / 2));
      elem.appendChild(background);

      int inset = (int) ((3 + strokeWidth) * scale);

      Element foreground = document.createElement("ellipse");
      foreground.setAttribute("fill", "none");
      foreground.setAttribute("stroke", strokeColor);
      foreground
          .setAttribute("stroke-width", String.valueOf(strokeWidth));

      foreground.setAttribute("cx", String.valueOf(x + w / 2));
      foreground.setAttribute("cy", String.valueOf(y + h / 2));
      foreground.setAttribute("rx", String.valueOf(w / 2 - inset));
      foreground.setAttribute("ry", String.valueOf(h / 2 - inset));
      elem.appendChild(foreground);
    }
    else if (shape.equals(mxConstants.SHAPE_RHOMBUS))
    {
      elem = document.createElement("path");

      String d = "M " + (x + w / 2) + " " + y + " L " + (x + w) + " "
          + (y + h / 2) + " L " + (x + w / 2) + " " + (y + h) + " L "
          + x + " " + (y + h / 2);

      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_TRIANGLE))
    {
      elem = document.createElement("path");
      String direction = mxUtils.getString(style,
          mxConstants.STYLE_DIRECTION, "");
      String d = null;

      if (direction.equals(mxConstants.DIRECTION_NORTH))
      {
        d = "M " + x + " " + (y + h) + " L " + (x + w / 2) + " " + y
            + " L " + (x + w) + " " + (y + h);
      }
      else if (direction.equals(mxConstants.DIRECTION_SOUTH))
      {
        d = "M " + x + " " + y + " L " + (x + w / 2) + " " + (y + h)
            + " L " + (x + w) + " " + y;
      }
      else if (direction.equals(mxConstants.DIRECTION_WEST))
      {
        d = "M " + (x + w) + " " + y + " L " + x + " " + (y + h / 2)
            + " L " + (x + w) + " " + (y + h);
      }
      else
      // east
      {
        d = "M " + x + " " + y + " L " + (x + w) + " " + (y + h / 2)
            + " L " + x + " " + (y + h);
      }

      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_HEXAGON))
    {
      elem = document.createElement("path");
      String direction = mxUtils.getString(style,
          mxConstants.STYLE_DIRECTION, "");
      String d = null;

      if (direction.equals(mxConstants.DIRECTION_NORTH)
          || direction.equals(mxConstants.DIRECTION_SOUTH))
      {
        d = "M " + (x + 0.5 * w) + " " + y + " L " + (x + w) + " "
            + (y + 0.25 * h) + " L " + (x + w) + " "
            + (y + 0.75 * h) + " L " + (x + 0.5 * w) + " "
            + (y + h) + " L " + x + " " + (y + 0.75 * h) + " L "
            + x + " " + (y + 0.25 * h);
      }
      else
      {
        d = "M " + (x + 0.25 * w) + " " + y + " L " + (x + 0.75 * w)
            + " " + y + " L " + (x + w) + " " + (y + 0.5 * h)
            + " L " + (x + 0.75 * w) + " " + (y + h) + " L "
            + (x + 0.25 * w) + " " + (y + h) + " L " + x + " "
            + (y + 0.5 * h);
      }

      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_CLOUD))
    {
      elem = document.createElement("path");

      String d = "M " + (x + 0.25 * w) + " " + (y + 0.25 * h) + " C "
          + (x + 0.05 * w) + " " + (y + 0.25 * h) + " " + x + " "
          + (y + 0.5 * h) + " " + (x + 0.16 * w) + " "
          + (y + 0.55 * h) + " C " + x + " " + (y + 0.66 * h) + " "
          + (x + 0.18 * w) + " " + (y + 0.9 * h) + " "
          + (x + 0.31 * w) + " " + (y + 0.8 * h) + " C "
          + (x + 0.4 * w) + " " + (y + h) + " " + (x + 0.7 * w) + " "
          + (y + h) + " " + (x + 0.8 * w) + " " + (y + 0.8 * h)
          + " C " + (x + w) + " " + (y + 0.8 * h) + " " + (x + w)
          + " " + (y + 0.6 * h) + " " + (x + 0.875 * w) + " "
          + (y + 0.5 * h) + " C " + (x + w) + " " + (y + 0.3 * h)
          + " " + (x + 0.8 * w) + " " + (y + 0.1 * h) + " "
          + (x + 0.625 * w) + " " + (y + 0.2 * h) + " C "
          + (x + 0.5 * w) + " " + (y + 0.05 * h) + " "
          + (x + 0.3 * w) + " " + (y + 0.05 * h) + " "
          + (x + 0.25 * w) + " " + (y + 0.25 * h);

      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_ACTOR))
    {
      elem = document.createElement("path");
      double width3 = w / 3;

      String d = " M " + x + " " + (y + h) + " C " + x + " "
          + (y + 3 * h / 5) + " " + x + " " + (y + 2 * h / 5) + " "
          + (x + w / 2) + " " + (y + 2 * h / 5) + " C "
          + (x + w / 2 - width3) + " " + (y + 2 * h / 5) + " "
          + (x + w / 2 - width3) + " " + y + " " + (x + w / 2) + " "
          + y + " C " + (x + w / 2 + width3) + " " + y + " "
          + (x + w / 2 + width3) + " " + (y + 2 * h / 5) + " "
          + (x + w / 2) + " " + (y + 2 * h / 5) + " C " + (x + w)
          + " " + (y + 2 * h / 5) + " " + (x + w) + " "
          + (y + 3 * h / 5) + " " + (x + w) + " " + (y + h);

      elem.setAttribute("d", d + " Z");
    }
    else if (shape.equals(mxConstants.SHAPE_CYLINDER))
    {
      elem = document.createElement("g");
      background = document.createElement("path");

      double dy = Math.min(40, Math.floor(h / 5));
      String d = " M " + x + " " + (y + dy) + " C " + x + " "
          + (y - dy / 3) + " " + (x + w) + " " + (y - dy / 3) + " "
          + (x + w) + " " + (y + dy) + " L " + (x + w) + " "
          + (y + h - dy) + " C " + (x + w) + " " + (y + h + dy / 3)
          + " " + x + " " + (y + h + dy / 3) + " " + x + " "
          + (y + h - dy);
      background.setAttribute("d", d + " Z");
      elem.appendChild(background);

      Element foreground = document.createElement("path");
      d = "M " + x + " " + (y + dy) + " C " + x + " " + (y + 2 * dy)
          + " " + (x + w) + " " + (y + 2 * dy) + " " + (x + w) + " "
          + (y + dy);

      foreground.setAttribute("d", d);
      foreground.setAttribute("fill", "none");
      foreground.setAttribute("stroke", strokeColor);
      foreground
          .setAttribute("stroke-width", String.valueOf(strokeWidth));

      elem.appendChild(foreground);
    }
    else
    {
      elem = document.createElement("rect");

      elem.setAttribute("x", String.valueOf(x));
      elem.setAttribute("y", String.valueOf(y));
      elem.setAttribute("width", String.valueOf(w));
      elem.setAttribute("height", String.valueOf(h));

      if (mxUtils.isTrue(style, mxConstants.STYLE_ROUNDED, false))
      {
        elem.setAttribute("rx", String.valueOf(w
            * mxConstants.RECTANGLE_ROUNDING_FACTOR));
        elem.setAttribute("ry", String.valueOf(h
            * mxConstants.RECTANGLE_ROUNDING_FACTOR));
      }
    }

    Element bg = background;

    if (bg == null)
    {
      bg = elem;
    }

    bg.setAttribute("fill", fillColor);
    bg.setAttribute("stroke", strokeColor);
    bg.setAttribute("stroke-width", String.valueOf(strokeWidth));

    // Adds the shadow element
    Element shadowElement = null;

    if (mxUtils.isTrue(style, mxConstants.STYLE_SHADOW, false)
        && !fillColor.equals("none"))
    {
      shadowElement = (Element) bg.cloneNode(true);

      shadowElement.setAttribute("transform",
          mxConstants.SVG_SHADOWTRANSFORM);
      shadowElement.setAttribute("fill", mxConstants.W3C_SHADOWCOLOR);
      shadowElement.setAttribute("stroke", mxConstants.W3C_SHADOWCOLOR);
      shadowElement.setAttribute("stroke-width", String
          .valueOf(strokeWidth));

      appendSvgElement(shadowElement);
    }

    // Applies rotation
    double rotation = mxUtils.getDouble(style, mxConstants.STYLE_ROTATION);

    if (rotation != 0)
    {
      int cx = x + w / 2;
      int cy = y + h / 2;

      elem.setAttribute("transform", "rotate(" + rotation + "," + cx
          + "," + cy + ")");

      if (shadowElement != null)
      {
        shadowElement.setAttribute("transform", "rotate(" + rotation
            + "," + cx + "," + cy + ") "
            + mxConstants.SVG_SHADOWTRANSFORM);
      }
    }

    // Applies opacity
    float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY, 100);

    if (opacity != 100)
    {
      String value = String.valueOf(opacity / 100);
      elem.setAttribute("fill-opacity", value);
      elem.setAttribute("stroke-opacity", value);

      if (shadowElement != null)
      {
        shadowElement.setAttribute("fill-opacity", value);
        shadowElement.setAttribute("stroke-opacity", value);
      }
    }

    if (mxUtils.isTrue(style, mxConstants.STYLE_DASHED))
    {
      elem.setAttribute("stroke-dasharray", "3, 3");
    }

    appendSvgElement(elem);

    return elem;
  }

  /**
   * Draws the given lines as segments between all points of the given list
   * of mxPoints.
   *
   * @param pts List of points that define the line.
   * @param style Style to be used for painting the line.
   */
  public Element drawLine(List<mxPoint> pts, Map<String, Object> style)
  {
    Element group = document.createElement("g");
    Element path = document.createElement("path");

    String strokeColor = mxUtils.getString(style,
        mxConstants.STYLE_STROKECOLOR);
    float tmpStroke = (mxUtils.getFloat(style,
        mxConstants.STYLE_STROKEWIDTH, 1));
    float strokeWidth = (float) (tmpStroke * scale);

    if (strokeColor != null && strokeWidth > 0)
    {
      // Draws the start marker
      Object marker = style.get(mxConstants.STYLE_STARTARROW);

      mxPoint pt = pts.get(1);
      mxPoint p0 = pts.get(0);
      mxPoint offset = null;

      if (marker != null)
      {
        float size = (mxUtils.getFloat(style,
            mxConstants.STYLE_STARTSIZE,
            mxConstants.DEFAULT_MARKERSIZE));
        offset = drawMarker(group, marker, pt, p0, size, tmpStroke,
            strokeColor);
      }
      else
      {
        double dx = pt.getX() - p0.getX();
        double dy = pt.getY() - p0.getY();

        double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
        double nx = dx * strokeWidth / dist;
        double ny = dy * strokeWidth / dist;

        offset = new mxPoint(nx / 2, ny / 2);
      }

      // Applies offset to the point
      if (offset != null)
      {
        p0 = (mxPoint) p0.clone();
        p0.setX(p0.getX() + offset.getX());
        p0.setY(p0.getY() + offset.getY());

        offset = null;
      }

      // Draws the end marker
      marker = style.get(mxConstants.STYLE_ENDARROW);

      pt = pts.get(pts.size() - 2);
      mxPoint pe = pts.get(pts.size() - 1);

      if (marker != null)
      {
        float size = (mxUtils.getFloat(style,
            mxConstants.STYLE_ENDSIZE,
            mxConstants.DEFAULT_MARKERSIZE));
        offset = drawMarker(group, marker, pt, pe, size, tmpStroke,
            strokeColor);
      }
      else
      {
        double dx = pt.getX() - p0.getX();
        double dy = pt.getY() - p0.getY();

        double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
        double nx = dx * strokeWidth / dist;
        double ny = dy * strokeWidth / dist;

        offset = new mxPoint(nx / 2, ny / 2);
      }

      // Applies offset to the point
      if (offset != null)
      {
        pe = (mxPoint) pe.clone();
        pe.setX(pe.getX() + offset.getX());
        pe.setY(pe.getY() + offset.getY());

        offset = null;
      }

      // Draws the line segments
      pt = p0;
      String d = "M " + pt.getX() + " " + pt.getY();

      for (int i = 1; i < pts.size() - 1; i++)
      {
        pt = pts.get(i);
        d += " L " + pt.getX() + " " + pt.getY();
      }

      d += " L " + pe.getX() + " " + pe.getY();

      path.setAttribute("d", d);
      path.setAttribute("stroke", strokeColor);
      path.setAttribute("fill", "none");
      path.setAttribute("stroke-width", String.valueOf(strokeWidth));

      if (mxUtils.isTrue(style, mxConstants.STYLE_DASHED))
      {
        path.setAttribute("stroke-dasharray", "3, 3");
      }

      group.appendChild(path);
      appendSvgElement(group);
    }

    return group;
  }

  /**
   * Draws the specified marker as a child path in the given parent.
   */
  public mxPoint drawMarker(Element parent, Object type, mxPoint p0,
      mxPoint pe, float size, float strokeWidth, String color)
  {
    mxPoint offset = null;

    // Computes the norm and the inverse norm
    double dx = pe.getX() - p0.getX();
    double dy = pe.getY() - p0.getY();

    double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
    double absSize = size * scale;
    double nx = dx * absSize / dist;
    double ny = dy * absSize / dist;

    pe = (mxPoint) pe.clone();
    pe.setX(pe.getX() - nx * strokeWidth / (2 * size));
    pe.setY(pe.getY() - ny * strokeWidth / (2 * size));

    nx *= 0.5 + strokeWidth / 2;
    ny *= 0.5 + strokeWidth / 2;

    Element path = document.createElement("path");
    path.setAttribute("stroke-width", String.valueOf(strokeWidth * scale));
    path.setAttribute("stroke", color);
    path.setAttribute("fill", color);

    String d = null;

    if (type.equals(mxConstants.ARROW_CLASSIC)
        || type.equals(mxConstants.ARROW_BLOCK))
    {
      d = "M "
          + pe.getX()
          + " "
          + pe.getY()
          + " L "
          + (pe.getX() - nx - ny / 2)
          + " "
          + (pe.getY() - ny + nx / 2)
          + ((!type.equals(mxConstants.ARROW_CLASSIC)) ? "" : " L "
              + (pe.getX() - nx * 3 / 4) + " "
              + (pe.getY() - ny * 3 / 4)) + " L "
          + (pe.getX() + ny / 2 - nx) + " "
          + (pe.getY() - ny - nx / 2) + " z";
    }
    else if (type.equals(mxConstants.ARROW_OPEN))
    {
      nx *= 1.2;
      ny *= 1.2;

      d = "M " + (pe.getX() - nx - ny / 2) + " "
          + (pe.getY() - ny + nx / 2) + " L " + (pe.getX() - nx / 6)
          + " " + (pe.getY() - ny / 6) + " L "
          + (pe.getX() + ny / 2 - nx) + " "
          + (pe.getY() - ny - nx / 2) + " M " + pe.getX() + " "
          + pe.getY();
      path.setAttribute("fill", "none");
    }
    else if (type.equals(mxConstants.ARROW_OVAL))
    {
      nx *= 1.2;
      ny *= 1.2;
      absSize *= 1.2;

      d = "M " + (pe.getX() - ny / 2) + " " + (pe.getY() + nx / 2)
          + " a " + (absSize / 2) + " " + (absSize / 2) + " 0  1,1 "
          + (nx / 8) + " " + (ny / 8) + " z";
    }
    else if (type.equals(mxConstants.ARROW_DIAMOND))
    {
      d = "M " + (pe.getX() + nx / 2) + " " + (pe.getY() + ny / 2)
          + " L " + (pe.getX() - ny / 2) + " " + (pe.getY() + nx / 2)
          + " L " + (pe.getX() - nx / 2) + " " + (pe.getY() - ny / 2)
          + " L " + (pe.getX() + ny / 2) + " " + (pe.getY() - nx / 2)
          + " z";
    }

    if (d != null)
    {
      path.setAttribute("d", d);
      parent.appendChild(path);
    }

    return offset;
  }

  /**
   * Draws the specified text either using drawHtmlString or using drawString.
   *
   * @param text Text to be painted.
   * @param x X-coordinate of the text.
   * @param y Y-coordinate of the text.
   * @param w Width of the text.
   * @param h Height of the text.
   * @param style Style to be used for painting the text.
   */
  public Object drawText(String text, int x, int y, int w, int h,
      Map<String, Object> style)
  {
    Element elem = null;
    String fontColor = mxUtils.getString(style,
        mxConstants.STYLE_FONTCOLOR, "black");
    String fontFamily = mxUtils.getString(style,
        mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILIES);
    int fontSize = (int) (mxUtils.getInt(style, mxConstants.STYLE_FONTSIZE,
        mxConstants.DEFAULT_FONTSIZE) * scale);

    if (text != null && text.length() > 0)
    {
      elem = document.createElement("text");

      // Applies the opacity
      float opacity = mxUtils.getFloat(style,
          mxConstants.STYLE_TEXT_OPACITY, 100);

      if (opacity != 100)
      {
        String value = String.valueOf(opacity / 100);
        elem.setAttribute("fill-opacity", value);
        elem.setAttribute("stroke-opacity", value);
      }

      elem.setAttribute("text-anchor", "middle");
      elem.setAttribute("font-weight", "normal");
      elem.setAttribute("font-decoration", "none");

      elem.setAttribute("font-size", String.valueOf(fontSize));
      elem.setAttribute("font-family", fontFamily);
      elem.setAttribute("fill", fontColor);

      String[] lines = text.split("\n");
      y += fontSize
          + (h - lines.length * (fontSize + mxConstants.LINESPACING))
          / 2 - 2;

      for (int i = 0; i < lines.length; i++)
      {
        Element tspan = document.createElement("tspan");

        tspan.setAttribute("x", String.valueOf(x + w / 2));
        tspan.setAttribute("y", String.valueOf(y));

        tspan.appendChild(document.createTextNode(lines[i]));
        elem.appendChild(tspan);

        y += fontSize + mxConstants.LINESPACING;
      }

      appendSvgElement(elem);
    }

    return elem;
  }

}
TOP

Related Classes of com.mxgraph.canvas.mxSvgCanvas

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.